﻿using System;
using System.Threading.Tasks;
using System.Windows.Threading;

namespace WeChat.UI.Command
{
    public class AsyncCommand<T> : AsyncCommandBase
    {
        readonly Func<T, bool> _canExecute;
        readonly Func<T, Task> _execute;
        bool _isExecuting;

        public AsyncCommand(Func<T, Task> execute, Func<T, bool> canExecute = null)
        {
            _canExecute = canExecute;
            _execute = execute;
        }

        public override bool CanExecute(object? parameter)
        {
            if (_isExecuting)
                return false;
            if (_canExecute is null)
                return true;
            return _canExecute(parameter is T t ? t : default);
        }

        public override async Task ExecuteAsync(object? parameter)
        {
            if (_execute != null)
            {
                RaiseCanExecuteChanged();
                _isExecuting = true;
                var dispatcher = Dispatcher.CurrentDispatcher;
                await Task.Run(async delegate
                {
                    try
                    {
                        await _execute(parameter is T t ? t : default).ConfigureAwait(false);
                    }
                    catch (Exception)
                    {
                    }
                    finally
                    {
                        _isExecuting = false;
                        dispatcher?.Invoke(RaiseCanExecuteChanged);
                    }
                }).ConfigureAwait(false);
            }
        }

    }
}
